<template>
  <div class="app-container">
    <div class="filter-container">
      <span v-for="(c,i) in showConditions" :key="i" style="margin-left: 5px;">
        <el-input
          v-if="c.type=='input'"
          v-model="listQuery[c.property]"
          size="small"
          :placeholder="c.label"
          style="width: 200px; "
          class="filter-item"
          @keyup.enter.native="handleFilter"
        />
        <el-date-picker
          v-else-if="c.type=='date-range'"
          v-model="listQuery[c.property]"
          type="daterange"
          value-format="yyyy-MM-dd"
          align="left"
          unlink-panels
          range-separator="至"
          :start-placeholder="c.label+':  开始'"
          end-placeholder="结束"
          :picker-options="pickerOptions"
          size="small"
          class="filter-item"
          @keyup.enter.native="handleFilter"
        />
        <el-date-picker
          v-else-if="c.type=='date'"
          v-model="listQuery[c.property]"
          type="date"
          value-format="yyyy-MM-dd"
          align="left"
          unlink-panels
          :placeholder="c.label"
          :picker-options="pickerOptions"
          size="small"
          class="filter-item"
          @keyup.enter.native="handleFilter"
        />
      </span>
      <el-button v-waves class="filter-item" size="small" type="primary" icon="el-icon-search" @click="handleFilter">
        查询
      </el-button>
      <el-button class="filter-item" style="margin-left: 10px;" size="small" type="primary" icon="el-icon-edit" @click="handleCreate">
        添加
      </el-button>
      <el-button class="filter-item" style="margin-left: 0px;" size="small" icon="el-icon-setting" @click="pageSettingVisible=true">
        页面设置
      </el-button>
    </div>

    <el-table
      :key="tableKey"
      v-loading="listLoading"
      :data="list"
      border
      fit
      highlight-current-row
      style="width: 100%;"
      @sort-change="sortChange"
      @header-dragend="headerDragend"
    >
      <el-table-column
        v-for="(col, index) in showTheads"
        :key="index"
        :prop="col.property"
        :sortable="col.sort"
        :sort-orders="['ascending', 'descending']"
        :label="col.label"
        :width="col.width"
      >
        <template slot-scope="{row}">
          <span v-if="col.edit">
            <el-input v-if="row.edit" v-model="row[col.property]" class="edit-input" size="mini" />
            <span v-else>{{ row[col.property] }}</span>
          </span>
          <span v-else>{{ row[col.property] }}</span>
        </template>
      </el-table-column>
      <!--操作Button-->
      <el-table-column v-if="!isDropMenu" fixed="right" label="操作" align="center" min-width="230">
        <template slot="header">
          <el-checkbox v-model="isDropMenu" class="filter-item" style="margin-left:15px;" @change="tableKey=tableKey+1">
            平铺 > 下拉
          </el-checkbox>
        </template>
        <template slot-scope="{row}">
          <el-button v-show="row.edit" type="success" size="mini" style="margin-left: 0px;" @click="cancelEdit(row)">取消</el-button>
          <el-button v-if="row.edit" type="success" size="mini" style="margin-left: 0px;" @click="confirmEdit(row)">保存</el-button>
          <el-button v-else type="primary" size="mini" style="margin-left: 0px;" @click="row.edit=!row.edit">编辑</el-button>
          <el-button slot="reference" size="mini" type="danger" @click="handleDelete(row, $index)">删除</el-button>
        </template>
      </el-table-column>

      <el-table-column v-else fixed="right" label="操作" align="center" min-width="140">
        <template slot="header">
          <el-checkbox v-model="isDropMenu" class="filter-item" style="margin-left:15px;" @change="tableKey=tableKey+1">
            下拉 > 平铺
          </el-checkbox>
        </template>
        <template slot-scope="{row, $index}">
          <el-button v-show="row.edit" type="success" size="mini" style="margin-left: 0px;" @click="cancelEdit(row)">取消</el-button>
          <el-button v-if="row.edit" type="success" size="mini" style="margin-left: 0px;" @click="confirmEdit(row)">保存</el-button>
          <el-dropdown v-else @command="handleCommand">
            <el-button type="primary" size="mini">
              菜单<i class="el-icon-arrow-down el-icon--right" />
            </el-button>
            <el-dropdown-menu slot="dropdown">
              <el-dropdown-item :command="beforeHandleCommand(row, 'update', $index)">编辑</el-dropdown-item>
              <el-dropdown-item :command="beforeHandleCommand(row, 'delete', $index)">删除</el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>
        </template>
      </el-table-column>

    </el-table>

    <!-- 分页 -->
    <pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getList" />

    <!-- 添加弹出框 -->
    <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
      <add-form ref="addForm" :row="row" :isFromFather="true" @createResult="createResult"/>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">
          取消
        </el-button>
        <el-button type="primary" @click="dialogStatus==='create'?createData():updateData()">
          保存
        </el-button>
      </div>
    </el-dialog>

    <!-- 页面设置 -->
    <el-dialog :visible.sync="pageSettingVisible" title="页面布局参数设置">
      <div>温馨提示：</div>
      <div>1，列表宽度可左右拖动调整，调整后，系统将自动进行本地记忆。</div>
      <div>2，页面参数存储在电脑本地；清除浏览器缓存将自动清除所有页面参数。</div>
      <div>
        <h3>查询条件：</h3>
        <el-checkbox-group v-model="conditionCheckboxVal">
          <el-checkbox v-for="(c,i) in conditionOptions" :key="i" :label="c.property" style="width: 150px;">{{ c.label }}</el-checkbox>
        </el-checkbox-group>
      </div>
      <div>
        <h3>列表显示列：</h3>
        <el-checkbox-group v-model="checkboxVal">
          <el-checkbox v-for="(thead,index) in theadOptions" :key="index" :label="thead.property" style="width: 150px;">{{ thead.label }}</el-checkbox>
        </el-checkbox-group>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="savePageSetting">保存</el-button>
      </span>
    </el-dialog>

  </div>
</template>

<script>
import { fetchList, updateApi, deleteApi } from './api'
import waves from '@/directive/waves' // waves directive
import { parseTime, reorgQueryParams } from '@/utils'
import storageUtil from '@/utils/StorageUtil'
import Pagination from '@/components/Pagination' // secondary package based on el-pagination
import AddForm from './add.vue' // add form form dialog
// 从当前View的私有数据对象中取数据
import { ConditionShowListCkedKey, ColumnShowListCkedKey, isDropMenuKey, ColumnShowListWidthKey, conditionOptions, theadOptions, pickerOptions, pickerOptionsSingleDate } from './data'

export default {
  name: 'TLogErpComplexListLineEdit',
  components: { Pagination, AddForm },
  directives: { waves },

  props: {
    // 当作为侧边日历查询的子组件时，接收父组件的传值，watch中查询
    queryDateArr: Array
  },

  filters: {
    statusFilter(status) {
      const statusMap = {
        published: 'success',
        draft: 'info',
        deleted: 'danger'
      }
      return statusMap[status]
    }
  },

  data() {
    return {
      tableKey: 0,
      // 控制行尾菜单显示模式（下拉->平铺）
      isDropMenu: storageUtil.readBool(isDropMenuKey),
      // 默认表头控制
      theadOptions: theadOptions,
      checkboxVal: [], // checkboxVal
      showTheads: [], // 默认表头 Default header
      // 查询条件
      conditionOptions: conditionOptions,
      conditionCheckboxVal: [], // 当前checkbox选中的值
      showConditions: [], // 当前显示的condition
      // 列表
      list: null,
      total: 0,
      listLoading: true,
      listQuery: {
        page: 1,
        limit: 20,
        createdate: [] // 不加此项，watch里监控侧边日历父组件，传的日期参数，有问题； 子页面时间查询框清不掉查询参数。
      },
      importanceOptions: [1, 2, 3],
      sortOptions: [{ label: 'ID Ascending', key: '+id' }, { label: 'ID Descending', key: '-id' }],
      statusOptions: ['published', 'draft', 'deleted'],
      dialogFormVisible: false,
      dialogStatus: '',
      textMap: {
        update: 'Edit',
        create: 'Create'
      },
      downloadLoading: false,
      pickerOptions: pickerOptions,
      pickerOptionsSingleDate: pickerOptionsSingleDate,
      row: {},
      pageSettingVisible: false // 页面布局设置
    }
  },

  watch: {
    conditionCheckboxVal(valArr) {
      this.showConditions = this.conditionOptions.filter(i => valArr.indexOf(i.property) >= 0)
    },
    checkboxVal(valArr) {
      this.showTheads = this.theadOptions.filter(i => valArr.indexOf(i.property) >= 0)
      this.tableKey = this.tableKey + 1// 为了保证table 每次都会重渲 In order to ensure the table will be re-rendered each time
    },
    isDropMenu(val) {
      storageUtil.saveBool(isDropMenuKey, val)
    },
    // 当作为侧边日历查询的子组件时，接收父组件的传值，watch中查询
    queryDateArr(val) {
      this.listQuery.createdate = val // 默认用createdate作查询参数
      this.handleFilter()
    }
  },

  created() {
    this.initLayout()
    this.getList()
  },

  methods: {
    initLayout() {
      // 显示列处理
      const defaultCheckedThead = []
      theadOptions.forEach(col => {
        if (col.default) {
          defaultCheckedThead.push(col.property)
        }
      })
      // read localstorage first
      const columnShowListCked = storageUtil.readArr(ColumnShowListCkedKey)
      if (columnShowListCked.length === 0) {
        this.checkboxVal = defaultCheckedThead
      } else {
        this.checkboxVal = columnShowListCked
      }
      // 查询条件处理
      const defaultCheckedCondition = []
      conditionOptions.forEach(col => {
        if (col.default) {
          defaultCheckedCondition.push(col.property)
        }
      })
      // read localstorage first
      const showConditionsCked = storageUtil.readArr(ConditionShowListCkedKey)
      if (showConditionsCked.length === 0) {
        this.conditionCheckboxVal = defaultCheckedCondition
      } else {
        this.conditionCheckboxVal = showConditionsCked
      }
    },

    getList() {
      console.log(this.listQuery)
      this.listLoading = true
      // 重组查询条件
      const params = Object.assign({}, this.listQuery)
      reorgQueryParams(params)
      // 查询
      fetchList(params).then(result => {
        const items = result.map.rows
        this.total = result.map.total

        // 备份数据，编辑还原用
        this.list = items.map(v => {
          this.$set(v, 'edit', false) // https://vuejs.org/v2/guide/reactivity.html
          v.original = Object.assign({}, v)
          return v
        })

        // Just to simulate the time of the request
        setTimeout(() => {
          this.listLoading = false
        }, 0.1 * 1000)
      })
    },
    handleFilter() {
      this.listQuery.page = 1
      this.getList()
    },
    sortChange(data) {
      const { prop, order } = data
      if (prop === 'id') {
        this.sortByID(order)
      }
    },
    sortByID(order) {
      if (order === 'ascending') {
        this.listQuery.sort = '+id'
      } else {
        this.listQuery.sort = '-id'
      }
      this.handleFilter()
    },

    // 列宽监听，本地存储
    // 存储格式: {name: 93, url: 115, deleteflag: 140, id: 121}
    headerDragend(newWidth, oldWidth, column, event) {
      const columnWidthJson = storageUtil.readObj(ColumnShowListWidthKey)
      columnWidthJson[column.property] = newWidth
      storageUtil.saveObj(ColumnShowListWidthKey, columnWidthJson)
      // 实时修改全局theadOptions中的width, 不然要刷新页面才从localstorage中读取width
      theadOptions.filter(c => c.property === column.property)[0].width = newWidth
    },

    handleCreate() {
      this.dialogStatus = 'create'
      this.dialogFormVisible = true
      // 消除上次出现的验证信息
      this.$nextTick(() => {
        this.$refs['addForm'].clearValidate()
        this.$refs['addForm'].resetTemp()
      })
    },
    // 调用子组件操作数据
    createData() {
      this.$refs['addForm'].createData()
    },
    // 子组件操作成功，回调此方法，关闭弹框、刷新
    createResult() {
      this.dialogFormVisible = false
      this.handleFilter()
    },

    cancelEdit(row) {
      // 还原原始值
      Object.keys(row).forEach(key => {
        if (key !== 'original' && key !== 'edit') {
          row[key] = row.original[key]
        }
      })
      row.edit = false
      // row.original.edit = false
      this.$message({
        message: '数据恢复到原始值',
        type: 'warning'
      })
    },
    confirmEdit(row) {
      const param = Object.assign({}, row)
      param.original = {}
      updateApi(param).then((result) => {
        if (result.success) {
          row.edit = false
          // 原始值：更新成最新输入仠
          Object.keys(row).forEach(key => {
            console.log(key)
            if (key !== 'original' && key !== 'edit') {
              row.original[key] = row[key]
            }
          })
          this.$notify({
            title: '成功',
            message: '数据更新成功',
            type: 'success',
            duration: 2000
          })
        }
      })
    },

    // 下拉操作菜单
    beforeHandleCommand(row, command, index) {
      return {
        'index': index,
        'row': row,
        'command': command
      }
    },
    handleCommand(command) {
      const row = command.row
      switch (command.command) {
        case 'update': {
          row.edit = !row.edit
          break
        }
        case 'delete': {
          this.handleDelete(row)
          break
        }
      }
    },
    // End

    handleDelete(row) {
      this.$confirm('确认删除吗？')
        .then(_ => {
          // delete api
          deleteApi({ id: '' + row.id }).then((result) => {
            if (result.success) {
              this.getList()
              this.$notify({
                title: '成功',
                message: '删除成功',
                type: 'success',
                duration: 2000
              })
            }
          })
          // end
        })
        .catch(_ => {})
    },
    // 保存页面设置参数
    savePageSetting() {
      // 查询条件
      storageUtil.saveArr(ConditionShowListCkedKey, this.conditionCheckboxVal)
      // 列
      storageUtil.saveArr(ColumnShowListCkedKey, this.checkboxVal)
      // close dialog
      this.pageSettingVisible = false
    },
    formatJson(filterVal) {
      return this.list.map(v => filterVal.map(j => {
        if (j === 'timestamp') {
          return parseTime(v[j])
        } else {
          return v[j]
        }
      }))
    },

    getSortClass: function(key) {
      const sort = this.listQuery.sort
      return sort === `+{key}` ? 'ascending' : 'descending'
    }
  }
}
</script>
<style>

</style>
